<?php
namespace Rexzy\Tool;

class Template {
    private $_temDir;
    private $_tempName;
    private $_type;
    public $vars = array();
    public $page;
    
    /**
     * 
     * @param string $type 要引入模板的文件类形（html / php）
     */
    public function __construct( $type ) {
        $this->_type = '.' . $type;
        $this->page = $paging = new \Rexzy\Tool\Page();
    }
    
    /**
     * 将当前控制器要用于display 函数里的变量注入函数环境内 
     * 
     * @param type $key 要注入display 环境的变量的名
     * @param type $value 要注入display 环境的变量的值
     */
    public function assign( $varName, $varValue = '' ) {
        if ( is_array( $varName ) ) {
            foreach ( $varName as $key => $value ) {
                $this->vars[ $key ] = $value;
            }
        } else {
            $this->vars[ $varName ] = $varValue;
        }
    }
    
    /** 
     * 设置进入模块的模板文件夹的目录路径
     * 
     * @param string $dir 模块的模板文件夹的目录路径
     */
    public function setDir( $dir ) {
        $this->_temDir = $dir;
    }
    
    /**
     * 设置进入模块控制器后的默认动作的模板文件路径
     * @param type $name
     */
    public function setTemplate( $name ) {
        $this->_temName = $name;
    }
    
    /**
     * 显示模板 
     * 
     * @param string $name 要更改的费默认动作的动作名称
     * @throws \Exception 当模板文件不存在时抛出异常
     */
    public function display( $name = '' ) {
        if ( $name == '' ) {
            $displayFile = $this->_temDir . $this->_temName . $this->_type;
        } else {
            $displayFile = $this->_temDir . $name . $this->_type;
        }
        
        if ( file_exists( $displayFile ) ) {
            $realFile = realpath( $displayFile );
            $cacheFileName = md5( $realFile ) . '.php';
            
            $dirPath = REXZY_ROOT . '/Data/templateCache';
            if ( ! is_dir( $dirPath ) ) {
                mkdir( $dirPath );
            }
            $cacheFile = $dirPath . '/' . $cacheFileName;
            
            extract( $this->vars );
            if ( file_exists( $cacheFile ) && ( filemtime( $cacheFile ) > filemtime( $realFile ) ) ) {
                    include $cacheFile;
            } else {
                include $this->_parse( $realFile );
            }
        } else {
            throw new \Exception("$displayFile not find!");
        }
    }
    
    /**
     *  模板解析函数 
     * 
     * @param string $file 应用模板文件的路径
     * @return string 解析后的模板的缓存文件路径
     */
    private function _parse( $file ) {
        $temContent = file_get_contents( $file );
        
        // 替换 echo 变量
        $temContent = preg_replace( '/\{\$(\S+?)\}/', '<?php echo $$1; ?>', $temContent );
        
        // 替换 foreach（只取值） 开始
        $temContent = preg_replace( '/\{foreach \$(\S+) \$(\S+)\}/', 
                '<?php foreach( $$1 as $$2 ) { ?>', $temContent );
        
        // 替换 foreach 结束
        $temContent = preg_replace( '/\{\/foreach\}/', '<?php } ?>', $temContent );
        
        // 替换 foreach（ 键值对 ） 开始
        $temContent = preg_replace( '/\{foreach \$(\S+) \$(\S+) \$(\S+)\}/', 
                '<?php foreach( $$1 as $$2 => $$3 ) { ?>', $temContent );
         
        // 替换 if 开始
        $temContent = preg_replace( '/\{if (.+?)\}/', '<?php if ( $1 ) { ', $temContent );
        
        // 替换 if 结束
        $temContent = preg_replace( '/\{\/if\}/', ' } ?>', $temContent );
        
        // 替换 else
        $temContent = preg_replace( '/\{else\}/', '<?php } else { ?>', $temContent );
        
        // 替换 else if
        $temContent = preg_replace( '/\{elseif (.+?)\}/', '<?php } else if ($1) { ?>', $temContent );
        
        // 替换 php 开始标签
        $temContent = preg_replace( '/\{php\}/', '<?php', $temContent );
        
        // 替换 php 结束标签
        $temContent = preg_replace( '/\{\/php\}/', '?>', $temContent );
        
        // 替换 函数 
        $temContent = preg_replace( '/\{:([^\(]+)(\([^\)]*\))\}/', '<?php $1$2; ?>', $temContent );
        
        // 替换生成链接地址的函数
        $temContent = preg_replace( '/\{(\\\Rexzy::url)(\([^\)]*\))\}/', '<?php echo $1$2; ?>', $temContent );
        
        //替换 include
        $temContent = preg_replace( '/\{include\((.+?)\)\}/', '<?php $this->display($1); ?>', $temContent );
        
        
        // 替换完保存到缓存目录
        $cacheFileName = md5( $file ) . '.php';
        $cacheFile = REXZY_ROOT . '/Data/templateCache/' . $cacheFileName;
        $fp = fopen( $cacheFile, 'w' );
        fwrite( $fp, $temContent );
        fclose( $fp );
        
        // 返回缓存路径
        return $cacheFile;
    }
}